#include "mysql_user.h"

#include <sstream>

#include "log.h"
#include "user-odb.hxx"

namespace chat {
// UserTable

bool UserTable::insert(const UserPtr& user) {
    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        db_->persist(*user);

        // 提交事务
        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("新增user[{}]失败: {}", user->user_id(), e.what());

        return false;
    }

    return true;
}

bool UserTable::update(const UserPtr& user) {
    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        db_->update(*user);

        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("更新user[{}]失败: {}", user->user_id(), e.what());

        return false;
    }

    return true;
}

UserPtr UserTable::select_by_nickname(
    const std::string& nickname) {
    UserPtr res = nullptr;

    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        res.reset(db_->query_one<User>(odb::query<User>::nickname == nickname));

        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("查找User[{}]失败: {}", nickname, e.what());

        return res;
    }

    return res;
}

UserPtr UserTable::select_by_user_id(const std::string& user_id) {
    UserPtr res = nullptr;

    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        res.reset(db_->query_one<User>(odb::query<User>::user_id == user_id));

        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("查找User[{}]失败: {}", user_id, e.what());

        return res;
    }

    return res;
}

UserPtr UserTable::select_by_phone(const std::string& phone) {
    UserPtr res = nullptr;

    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        res.reset(db_->query_one<User>(odb::query<User>::phone == phone));

        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("查找User[{}]失败: {}", phone, e.what());

        return res;
    }

    return res;
}

std::vector<User> UserTable::select_multi_by_ids(
    const std::vector<std::string>& id_list) {
    // select * from user where id in (id1, id2, id3, ...)

    std::vector<User> res;

    std::stringstream ss;
    ss << "user_id in (";
    for (auto& id : id_list) {
        ss << "'" << id << "',";
    }
    std::string condition = ss.str();
    condition.pop_back();
    condition += ")";

    LOG_DEBUG("condition: {}", condition);

    try {
        // 获取事务对象开启事务
        odb::transaction trans(db_->begin());

        odb::result<User> r(db_->query<User>(condition));

        for (auto& user : r) {
            res.push_back(user);
        }

        trans.commit();

    } catch (const std::exception& e) {
        LOG_ERROR("批量查找User失败: {}", e.what());

        return res;
    }

    return res;
}

// -------------------------------------------------------------------

}  // namespace chat